package com.twu.biblioteca;

import java.nio.channels.IllegalBlockingModeException;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;

/* Job: represents all operations that application is intended to do */
public class BibliotecaApp {
    Library library=new Library();
    //boolean shouldContinue=true;
    UIApplication UIApplication =new UIApplication();

    private List<MenuAction> classesToBeInvokedAsUser =new ArrayList<MenuAction>() {{add(new ListBooks(library, UIApplication));
        add(new ListMovies(library, UIApplication));
        add(new CheckoutBook(library, UIApplication));
        add(new CheckOutMovie(library, UIApplication));
        add(new ReturnBook(library, UIApplication));
        add(new ReturnMovie(library, UIApplication));
        add(new Profile(library, UIApplication));
        add(new Logout(library, UIApplication));}

    };
    static BibliotecaApp bibliotecaApp=new BibliotecaApp();
    private List<Login> initalMenu= new ArrayList<Login>(){{add(new LoginAsUser(library,UIApplication));add(new LoginAsLibrarian(library,UIApplication));add(new Quit(library, UIApplication));}};
    private List <MenuAction>classesToBeInvokedAsLibrarian=new ArrayList<MenuAction>(){{add(new ListBooks(library, UIApplication));
        add(new ListMovies(library, UIApplication)); add(new ListCheckedOutBooks(library, UIApplication));add(new ListCheckedOutMovies(library, UIApplication));
        add(new Logout(library, UIApplication));}};

    public static void main(String[] args) {

        bibliotecaApp.sendWelcome();


        try {
            bibliotecaApp.callLoginOperation();
        } catch (Exception e) {
            bibliotecaApp.UIApplication.display("Quitting Application");

        }


    }

    private void callLoginOperation() throws Exception {
        try {

            do {
                bibliotecaApp.sendInitialMenu();
                UIApplication.display("Enter Option");
                try {
                    int choice = UIApplication.acceptChoice();
                    ResultLogin resultLogin = initalMenu.get(choice).performAction();
                    Result result=resultLogin.getResult();
                    if (result.getIsSuccess()) {
                        UIApplication.displayMenuActionResult("\nSuccess :\n" + result.getMessage());
                        if(result.getMessage().equals("Logged in as User"))
                        {
                            Menu menu=new Menu();
                            menu.setMenuOptions(bibliotecaApp.classesToBeInvokedAsUser);
                            bibliotecaApp.callOperationPerfom(bibliotecaApp.classesToBeInvokedAsUser,menu,resultLogin.getUser());
                        }
                        else
                        {
                            Menu menu=new Menu();
                            menu.setMenuOptions(bibliotecaApp.classesToBeInvokedAsLibrarian);
                            bibliotecaApp.callOperationPerfom(bibliotecaApp.classesToBeInvokedAsLibrarian,menu,null);

                        }
                    } else
                        UIApplication.displayMenuActionResult("\nFail :\n" + result.getMessage());

                    }
                catch(InputMismatchException e)
                {

                    UIApplication.display("Invalid input");


                }


                }
             while (true);
        } catch(InterruptedException e)
        {
            UIApplication.display("Quitting Application");
        }

    }





    private void sendInitialMenu() {
        Menu initialMenu=new Menu();
        initialMenu.setMenuOptions(bibliotecaApp.initalMenu);
        UIApplication.displayMenu(initialMenu.getMenuOptions());
    }
    protected void callOperationPerfom(List<MenuAction> classestobeInvoked, Menu menu, String user) throws Exception {
        try
        {


            do {

                bibliotecaApp.sendMenu(menu);
                UIApplication.display("Enter Option");
                try {
                    int choice = UIApplication.acceptChoice();


                    Result result = classestobeInvoked.get(choice).performAction(user);
                    if (result.getIsSuccess()) {
                        UIApplication.displayMenuActionResult("Success :\n" + result.getMessage());
                    } else
                        UIApplication.displayMenuActionResult("Fail :\n" + result.getMessage());


                }
                catch (IndexOutOfBoundsException e)
                {
                    UIApplication.display("Invalid Menu Option");
                }
                catch(InputMismatchException e)
                {

                    UIApplication.display("Invalid input");                }
                catch(IllegalBlockingModeException e)
                {
                    throw new InterruptedException();
                }


            } while (true);
        }

        catch(InterruptedException e)
        {
            UIApplication.display("Logging out");
        }




    }





    protected  boolean sendWelcome() {
        return UIApplication.display("WELCOME");

    }

    protected  boolean sendMenu(Menu menu) {
        return UIApplication.displayMenu(menu.getMenuOptions());
    }

}
